

export class NumUnit implements Unit {

    cnUnit : Array<[string, number]> = [
        ["亿", 1_0000_0000],
        ["Y", 1_0000_0000],
        ["万", 1_0000],
        ["W", 1_0000],
        ["千", 1_000],
        ["K", 1_000],
        ["Q", 1_000],
    ];

    enUnit : Array<[string, number]> = [
        ["P", 1_000_000_000_000_000],
        ["T", 1_000_000_000_000],
        ["G", 1_000_000_000],
        ["M", 1_000_000],
        ["K", 1_000],
    ];


    parse(text: string): number {
        const pat = /(-?\d+\.?\d*)(.*)/
        const m = text.match(pat)
        if (m == null) {
            throw new Error("not a invalid input")
        }
        let num = Number.parseFloat(m[1])
        let unit = m[2].trim()
        for (let u of unit) {
            num = num * this.unitValue(u)
        }
        return num
    }

    format(num: number, local?: string): string {

        if (local === undefined) {
            return num.toString();
        }
        let [unitName, dec] = local.split(':')

        let units : Array<[string, number]>
        switch (unitName.toLocaleLowerCase()) {
            case "cn":
                units = this.cnUnit
                break
            case "en":
                units = this.enUnit
                break
            default:
                return num.toString();
        }

        let unit = ""
        let [lu, ln] = units[units.length - 1]
        while (num > ln) {
            for (let [u, n] of units) {
                if (num >= n) {
                    num = num / n
                    unit = u + unit
                    break;
                }
            }
        }

        let decNum = Number.parseInt(dec);
        if (Number.isNaN(decNum)) {
            return num.toString() + unit
        }else{
            return num.toFixed(decNum).replace(/\.?0+$/, '') + unit
        }
    }


    unitValue(unit: string) : number {
        let uu = unit.toLocaleUpperCase()

        let all = this.enUnit.concat(this.cnUnit);
        let found = all.find( ([u, n]) => u === uu) || ["", 1]
        return found[1]
    }
}